package xyz.xiezc.spider.statistic;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.*;
import cn.hutool.setting.Setting;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import xyz.xiezc.ioc.annotation.Inject;
import xyz.xiezc.spider.control.ScheduleCore;
import xyz.xiezc.spider.control.ScheduleImpl;
import xyz.xiezc.spider.upload.OssClient;
import xyz.xiezc.xhttp.common.PathMapping;

import java.io.File;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author wb-xzc291800
 * @date 2019/04/25 13:16
 */
@Slf4j
@PathMapping("/")
public class XSpiderController {

    @Inject
    Setting setting;

    @Inject
    Statistic statistic;

    @Inject
    Site site;

    @Inject
    ScheduleImpl schedule;


    @PathMapping("/checkAlbum")
    public String checkAlbum() throws SQLException {
        Session session = Session.create();
        List<Entity> xs_photo_album = session.findAll(Entity.create("xs_photo_album"));
        Map<String, List<Integer>> map = new HashMap<>();
        xs_photo_album.stream().forEach(entity -> {
            String title = entity.getStr("title");
            Integer id = entity.getInt("id");
            List<Integer> title1 = map.get(title);
            if (title1 == null) {
                title1 = new ArrayList<>();
                map.put(title, title1);
            }
            title1.add(id);
        });

        map.forEach((k, v) -> {
            if (v.size() > 1) {
                try {
                    int size = v.size();
                    for (int i = 1; i < size; i++) {
                        session.update(
                                Entity.create().set("album_id", v.get(0)),
                                Entity.create("xs_photo").set("album_id", v.get(i))
                        );
                        session.update(
                                Entity.create().set("album_id", v.get(0)),
                                Entity.create("xs_tag").set("album_id", v.get(i))
                        );
                        session.del(Entity.create("xs_photo_album").set("id", v.get(i)));
                    }

                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        });
        return "success";
    }

    @Inject
    ScheduleCore scheduleCore;

    @PathMapping("dealSSS")
    public String dela() throws SQLException {
        scheduleCore.dealFirstImg();
        return "success";
    }


    @PathMapping("/setting")
    public String getSetting(Map<String, String> param, Map<String, List<String>> headers) {
        JSONObject settingObj = (JSONObject) JSON.toJSON(setting);
        List<String> groups = setting.getGroups();
        for (String group : groups) {
            if (StrUtil.equals(group, "user")) {
                continue;
            }
            if (StrUtil.isNotBlank(group)) {
                settingObj.put(group, setting.getMap(group));
            }
        }
        return settingObj.toJSONString();
    }

    @PathMapping("/status")
    public String getStatus(Map<String, String> param, Map<String, List<String>> headers) {
        String response = JSON.toJSONString(site.getSatus());
        return response;
    }

    @PathMapping("/start")
    public String start(Map<String, String> param, Map<String, List<String>> headers) {
        schedule.startSpider();
        return "success";
    }

    @PathMapping("/addUrl")
    public String addUrl(Map<String, String> paramMap, Map<String, List<String>> headers) {
        String url = paramMap.get("url");
        if (StrUtil.isNotBlank(url)) {
            statistic.addSeedUrl(url);
            schedule.startSpider();
            return "success";

        }
        return "please give me url";
    }

    @PathMapping("/updateSetting")
    public String updateSetting(Map<String, String> param, Map<String, List<String>> headers) {
        String group = param.remove("group");
        Set<Map.Entry<String, String>> entries = param.entrySet();
        if (StrUtil.isNotBlank(group)) {
            for (Map.Entry<String, String> entry : entries) {
                setting.put(group, entry.getKey(), entry.getValue());
            }
        } else {
            for (Map.Entry<String, String> entry : entries) {
                setting.put(entry.getKey(), entry.getValue());
            }
        }
        return "success";
    }

    @Inject
    OssClient ossClient;


    @PathMapping("checkFileExist")
    public String checkFileExist() throws SQLException {
        String dir = setting.get("data.dir");
        int i = 26;
        Session session = Session.create();

        while (true) {
            Page page = new Page(i, 1000);
            PageResult<Entity> xs_photo = session.page(Entity.create("xs_photo"), page);
            log.info("page:{}, size:{}, totalPage:{}", i, 1000, xs_photo.getTotalPage());
            if (xs_photo == null || xs_photo.isEmpty()) {
                break;
            }
            i++;
            Map<Long, Entity> map = new HashMap<>();
            for (Entity entity : xs_photo) {
                String path = entity.getStr("path");
                boolean exist = FileUtil.exist(dir + path);
                if (exist) {
                    if (ossClient.exist(path)) {
                        if (entity.getInt("have_up") != 1) {
                            entity.set("have_up", 1);
                            map.put(entity.getLong("id"), entity);
                        }
                    } else {
                        if (entity.getInt("have_up") == 1) {
                            entity.set("have_up", null);
                            map.put(entity.getLong("id"), entity);
                        }
                    }
                } else {
                    entity.set("is_deleted", 1);
                    map.put(entity.getLong("id"), entity);
                }
                log.info("check path:{} end", path);
            }
            Set<Map.Entry<Long, Entity>> entries = map.entrySet();
            for (Map.Entry<Long, Entity> entityEntry : entries) {
                try {
                    session.update(entityEntry.getValue(), Entity.create("xs_photo").set("id", entityEntry.getKey()));
                    log.info("修改:id:{}  ; path:{}", entityEntry.getKey(), entityEntry.getValue().getStr("path"));
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return "success";

    }


    @PathMapping("/upOss")
    public String upOss() throws SQLException {
        String str = setting.getStr("data.dir");
        List<Entity> query = Db.use().query("select * from xs_photo where have_up is null");
        for (Entity entity : query) {
            String path = entity.getStr("path");
            try {
                if (path.startsWith("/")) {
                    path = path.substring(1);
                }
                ossClient.upObject(path, new File(str + "/" + path));
                Long id = entity.getLong("id");
                Db.use().update(Entity.create("xs_photo").set("path", path)
                                .set("have_up", 1),
                        Entity.create("xs_photo").set("id", id));
                log.info("upOSS, path:{}", path);
            } catch (SQLException e) {
                log.info("path:{} 上传OSS失败", path);
                e.printStackTrace();
            }

        }
        return query.size() + "";
    }

}